package userfunctions;

import userfunctions.packets.client.*;
import java.util.Date;
import java.util.Map;
import java.util.Vector;
import userfunctions.packets.*;

/**
 * Klasa klienta.
 * @brief Klasa pozwala na podstawowe operacje na koncie uzytkownika.
 * @author Kamil Woźnicki
 */
public class Client extends Person {
    /**
     * Metoda wykonująca wewnętrzny przelew.
     * @param src Konto źródłowe
     * @param dest Konto docelowa
     * @param kwota Kwota przelewu.
     * @return Jeżeli operacja powiodła się, metoda zwraca true. W przeciwnym
     * wypadku zwraca false.
     */
    public boolean przelewWewnetrzny(String src, String dest, float kwota) {
        return przelew(src, dest, kwota, PacketTransfer.TransferType.Internal);
    }
    
    /**
     * Metoda wykonująca zewnętrzny przelew.
     * @param src Konto źródłowe
     * @param dest Konto docelowa
     * @param kwota Kwota przelewu.
     * @return Jeżeli operacja powiodła się, metoda zwraca true. W przeciwnym
     * wypadku zwraca false.
     */
    public boolean przelewZewnetrzny(String src, String dest, float kwota) {
        return przelew(src, dest, kwota, PacketTransfer.TransferType.External);
    }
    
    private boolean przelew(String src, String dest, float kwota, PacketTransfer.TransferType type) {
        PacketTransfer transfer = new PacketTransfer(src, dest, kwota, type);
        
        sendPacket(transfer);
        
        return handleResponse();
    }

    /**
     * Metoda pobiera stan konta.
     * @param numerKonta Numer konta, dla którego zostanie pobrane saldo.
     * @return Metoda zwraca saldo. Jezeli konto nie istnieje metoda zwraca 0.
     */
    public float pobierzStanKonta(String numerKonta) {
        Map<String, String> mapa = pobierzDaneUzytkownika();
        
        float kwota = 0;
        
        try {
            kwota = Float.valueOf(mapa.get("stan_" + numerKonta));
        } catch (Exception e) {
        }
        return kwota;
    }
    
    /**
     * Tworzenie nowej lokaty na podstawie podanego numeru konta i kwoty.
     * @param numerKonta Numer konta, z ktorego zostana pobrane fundusze.
     * @param kwota Kwota pobrana z konta.
     * @return Wartosc logiczna okreslajaca poprawnosc operacji.
     */
    public boolean lokataStworz(String numerKonta, float kwota) {
        PacketLokata packet = new PacketLokata(numerKonta, kwota);
        sendPacket(packet);
        
        return handleResponse();
    }

    /**
     * Usuwanie lokaty i zwracanie kwoty na podane konto.
     * @param numerLokaty Numer usuwanej lokaty.
     * @param numerKonta Numer konta na ktore zostana przelane fundusze.
     * @return Wartosc logiczna okreslajaca poprawnosc operacji.
     */
    public boolean lokataUsun(String numerLokaty, String numerKonta) {
        PacketLokata packet = new PacketLokata(numerLokaty, numerKonta);
        sendPacket(packet);
        
        return handleResponse();
    }
    
    /**
     * Pobiera historie konta.
     * @param numer Numer konta ktorego informacje zostana pobrane.
     * @param from  Data od ktorej zostana zgromadzone informacje.
     * @param to    Data do ktorej beda pobrane informacje.
     * @return Lista operacji.
     */
    public Vector<String> pobierzHistorieKonta(String numer, Date from, Date to) {
        PacketGetHistory packet = new PacketGetHistory(numer, from, to);
        sendPacket(packet);
        
        return handleVector();
    }
    
    
    /**
     * Pobiera dane uzytkownika w postaci mapy.
     * @return Mapa kluczowana Stringiem zawierajaca informacje.
     */
    public Map<String, String> pobierzDaneUzytkownika() {
        PacketInformationRequest packet = new PacketInformationRequest(userId);
        sendPacket(packet);
        
        Packet response = recvPacket();
        
        if (response instanceof PacketInformationResponse) {
            PacketInformationResponse info = (PacketInformationResponse)response;
            
            return info.information;
        } else {
            return null;
        }
    }
}
